package com.qf.spring.service;

import com.qf.spring.utils.TransactionUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 王博康
 * @version 1.0
 * @project 02_spring
 * @description: TODO
 * @date 2022/3/4 15:08 星期五
 */
public class BeanFactory {
    public static UserService getService(){
        //创建一个原生对象，即最终要执行的代码
        UserService userService = new UserServiceImpl();
        /**
         * 创建一个代理对象
         * 参数1 类加载器
         * 参数2 创建代理对象的接口类型
         * 参数3 执行器匿名内部类对象-->调用方法时，具体要干什么
         * 在匿名内部类对象的方法中，编写次要业务要执行的代码，并调用原生对象要执行的核心代码，从而实现功能扩展，并返回同类型的代理对象
         */
        UserService o = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {

            /**
             * 当我们执行匿名的代理对象中的方法的时候，因为没有代码实现，所以是无法执行操作的，所以Java将代码进行了封装然后执行当前方法
             * @param proxy     当前的匿名对象
             * @param method    匿名对象正在执行的方法
             * @param args      匿名对象在执行时传递的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("匿名对象执行方法了" + method.getName());
                TransactionUtil.start();
                method.invoke(userService, args);
                System.out.println(userService.hashCode());
                TransactionUtil.commit();
                return null;
            }
        });
        return  o;


    }
}
